/*
 * DIM-SUM操作系统 -- 中断头文件
 *
 * Copyright (C) 2022 国科础石(重庆)软件有限公司
 *
 * 作者: Dong Peng <w-pengdong@kernelsoft.com>
 *
 * License terms: GNU General Public License (GPL) version 3
 *
 */

#ifndef __ASM_IRQFLAGS_H
#define __ASM_IRQFLAGS_H

#ifdef __KERNEL__

#include <asm/ptrace.h>
#include <asm/csr.h>
/**
 * CPU中断处理
 *	1、获取状态寄存器，并关闭中断
 *	2、打开中断
 *	3、关闭中断
 */
/* read interrupt enabled status */
static inline unsigned long arch_local_save_flags(void)
{
	return csr_read(sstatus);
}

/* unconditionally enable interrupts */
static inline void arch_local_irq_enable(void)
{
	csr_set(sstatus, SR_SIE);
}

/* unconditionally disable interrupts */
static inline void arch_local_irq_disable(void)
{
	csr_clear(sstatus, SR_SIE);
}

/* get status and disable interrupts */
static inline unsigned long arch_local_irq_save(void)
{
	return csr_read_clear(sstatus, SR_SIE);
}

/* test flags */
static inline int arch_irqs_disabled_flags(unsigned long flags)
{
	return !(flags & SR_SIE);
}

/* test hardware interrupt enable bit */
static inline int arch_irqs_disabled(void)
{
	return arch_irqs_disabled_flags(arch_local_save_flags());
}

/* set interrupt enabled status */
static inline void arch_local_irq_restore(unsigned long flags)
{
	csr_set(sstatus, flags & SR_SIE);
}


/**
 * 打开/关闭FIQ，目前未用
 */
#define local_fiq_enable()	//asm("msr	daifclr, #1" : : : "memory")
#define local_fiq_disable()	//asm("msr	daifset, #1" : : : "memory")

/**
 * 目前未用
 */
#define enable_async()	//asm("msr	daifclr, #4" : : : "memory")
#define disable_async()	//asm("msr	daifset, #4" : : : "memory")


#define DAIF_PROCCTX		0
#define DAIF_PROCCTX_NOIRQ	PSR_I_BIT

/* mask/save/unmask/restore all exceptions, including interrupts. */
static inline void local_daif_mask(void)
{
	asm volatile(
		"msr	daifset, #0xf		// local_daif_mask\n"
		:
		:
		: "memory");
}

static inline unsigned long local_daif_save(void)
{
	unsigned long flags;

	flags = arch_local_save_flags();

	local_daif_mask();

	return flags;
}

static inline void local_daif_unmask(void)
{
	asm volatile(
		"msr	daifclr, #0xf		// local_daif_unmask"
		:
		:
		: "memory");
}

static inline void local_daif_restore(unsigned long flags)
{
	arch_local_irq_restore(flags);
}

#endif

#endif
